package redis_util

import (
	"context"
	"encoding/json"
	"github.com/go-redis/redis/v8"
	"github.com/pkg/errors"
	"time"
	"trpg-common/config"
	"trpg-common/logger"
	"trpg-common/utils/json_util"
)

// 上下文变量
var ctx = context.Background()

// redis操作指针
var rdb *redis.Client

// 初始化*redis.Client
func init() {
	rdb = redis.NewClient(&redis.Options{
		Addr:     config.GetString("redis.addr"),
		Password: config.GetString("redis.password"),
		DB:       0,
	})
}

func SetString(key string, value string, expiration time.Duration) {
	err := rdb.Set(ctx, key, value, expiration).Err()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in operate redis"))
	}
}

func GetString(key string) string {
	val, err := rdb.Get(ctx, key).Result()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in operate redis"))
	}
	return val
}

func SetStruct(key string, value interface{}, expiration time.Duration) {
	bytes := json_util.Marshal(&value)
	err := rdb.Set(ctx, key, bytes, expiration).Err()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in operate redis"))
	}
}

func GetStruct(key string, value interface{}) {
	val, err := rdb.Get(ctx, key).Result()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in operate redis"))
	}
	json_util.UnMarshal([]byte(val), value)
}

func Remove(key string) {
	err := rdb.Del(ctx, key).Err()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in operate redis"))
	}
}

func ExpireKey(key string, expiration time.Duration) {
	err := rdb.Expire(ctx, key, expiration).Err()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in operate redis"))
	}
}

func RemoveWithError(key string) error {
	return rdb.Del(ctx, key).Err()
}

func SetStringWithError(key string, value string, expiration time.Duration) error {
	err := rdb.Set(ctx, key, value, expiration).Err()
	return err
}

func GetStringWithError(key string) (string, error) {
	val, err := rdb.Get(ctx, key).Result()
	return val, err
}

func SetStructWithError(key string, value interface{}, expiration time.Duration) error {
	bytes := json_util.Marshal(&value)
	err := rdb.Set(ctx, key, bytes, expiration).Err()
	return err
}

func GetStructWithError(key string, value interface{}) error {
	val, err := rdb.Get(ctx, key).Result()
	if err != nil {
		return err
	}
	err = json.Unmarshal([]byte(val), value)
	return err
}

func ExpireKeyWithError(key string, expiration time.Duration) error {
	return rdb.Expire(ctx, key, expiration).Err()
}
